package com.stox.client.ui.javafx.chartingy.widget;

import java.text.NumberFormat;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;

import com.stox.client.ui.javafx.chartingy.model.chart.PrimaryChart;
import com.stox.client.ui.javafx.chartingy.model.node.DataNode;
import com.stox.client.ui.javafx.chartingy.model.plot.Data;
import com.stox.client.ui.javafx.core.util.CSS;
import com.stox.client.ui.javafx.core.util.UI;
import com.stox.shared.i18n.MessageSource;
import com.stox.shared.model.Bar;
import com.stox.shared.model.Scrip;
import com.stox.shared.util.Constant;

public class BarInfoPanel extends VBox implements EventHandler<MouseEvent> {

	private final PrimaryChart primaryChart;
	private final GridPane grid = new GridPane();
	private final Label open = new Label();
	private final Label high = new Label();
	private final Label low = new Label();
	private final Label close = new Label();
	private final Label volume = new Label();
	private final Label date = new Label();
	private final Button closeButton = UI.mediumCrossButton(MessageSource.get("Close"));

	public BarInfoPanel(final PrimaryChart primaryChart) {
		this.primaryChart = primaryChart;
		UI.style(this, CSS.barInfoPanel);
		primaryChart.addEventFilter(MouseEvent.MOUSE_MOVED, this);
		primaryChart.addEventFilter(MouseEvent.MOUSE_DRAGGED, this);
		getChildren().add(createGrid());

		backgroundProperty().bind(primaryChart.getChartingView().backgroundProperty());
		layoutXProperty().bind(primaryChart.getChartContentArea().layoutXProperty());
		layoutYProperty().bind(primaryChart.getChartContentArea().layoutYProperty().add(primaryChart.getChartContentArea().heightProperty().subtract(heightProperty())));
	}

	private Node previousNode;
	DropShadow effect = new DropShadow(30, Color.WHITE);

	@Override
	public void handle(final MouseEvent event) {
		final int index = primaryChart.getDateAxis().getIndexForDisplay(event.getX());
		if ((index > -1) && (index < primaryChart.getPrimaryPlot().getData().size())) {
			final Data<Scrip, Bar> data = primaryChart.getPrimaryPlot().getData().get(index);
			final DataNode<?, ?> dataNode = data.getDataNode();
			if (null != dataNode) {
				if (null != previousNode) {
					previousNode.setEffect(null);
				}
				dataNode.setEffect(effect);
				previousNode = dataNode;
			}
			update(data.getExtraValue());
		}
	}

	private GridPane createGrid() {
		HBox.setHgrow(grid, Priority.ALWAYS);
		VBox.setVgrow(grid, Priority.ALWAYS);
		grid.setMaxHeight(Double.MAX_VALUE);
		grid.setMaxWidth(Double.MAX_VALUE);

		closeButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(final ActionEvent event) {
				setVisible(false);
			}
		});
		final HBox hbox = new HBox(date, closeButton);
		HBox.setHgrow(hbox, Priority.ALWAYS);
		hbox.setMaxWidth(Double.MAX_VALUE);
		HBox.setHgrow(date, Priority.ALWAYS);
		date.setMaxWidth(Double.MAX_VALUE);
		UI.style(date, CSS.left, CSS.barInfoDateLabel);
		UI.style(hbox, CSS.right);
		grid.add(hbox, 0, 0, 2, 1);

		grid.add(UI.style(new Label(MessageSource.get("Open")), CSS.left), 0, 1);
		grid.add(UI.style(open, CSS.right), 1, 1);
		open.setMaxWidth(Double.MAX_VALUE);
		grid.add(UI.style(new Label(MessageSource.get("High")), CSS.left), 0, 2);
		grid.add(UI.style(high, CSS.right), 1, 2);
		high.setMaxWidth(Double.MAX_VALUE);
		grid.add(UI.style(new Label(MessageSource.get("Low")), CSS.left), 0, 3);
		grid.add(UI.style(low, CSS.right), 1, 3);
		low.setMaxWidth(Double.MAX_VALUE);
		grid.add(UI.style(new Label(MessageSource.get("Close")), CSS.left), 0, 4);
		grid.add(UI.style(close, CSS.right), 1, 4);
		close.setMaxWidth(Double.MAX_VALUE);
		grid.add(UI.style(new Label(MessageSource.get("Volume")), CSS.left), 0, 5);
		grid.add(UI.style(volume, CSS.right), 1, 5);
		volume.setMaxWidth(Double.MAX_VALUE);

		return grid;
	}

	public void update(final Bar bar) {
		open.setText(Constant.numberFormat.format(bar.getOpen()));
		high.setText(Constant.numberFormat.format(bar.getHigh()));
		low.setText(Constant.numberFormat.format(bar.getLow()));
		close.setText(Constant.numberFormat.format(bar.getClose()));
		volume.setText(NumberFormat.getIntegerInstance().format(bar.getVolume()));
		date.setText(Constant.dateFormat.format(bar.getDate()));
	}

	public void setGridVisible(final boolean value) {
		grid.setVisible(value);
	}

}
